﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Kinlo.Drv.Drv.RJShortCircuitEnum;
using Kinlo.Drv.Drv.RJShortCirrcuitResult;
using Kinlo.Drv.DrvBases;
using System.IO;
using System.IO.Ports;
using Comm;

namespace Kinlo.Drv.Drv
{
    public class RJShortCircuitSerialPort
    {
        private SerialPort Clien;
        public bool IsOpen { get; set; }
        public RJShortCircuitSerialPort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits, int timeOut)
        {
            Clien = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
            Clien.ReadBufferSize = 2048;
            Clien.WriteBufferSize = 2048;
            Clien.DtrEnable = true;
            Clien.RtsEnable = true;
            Clien.ReadTimeout = Clien.WriteTimeout = 10 * 1000;
        }

        public Result Connect()
        {
            try
            {
                if (Clien.IsOpen) Clien.Close();
                Clien.Open();
                IsOpen = Clien.IsOpen;
                return new Result { Data = null, ErroMessage = null, IsSuccess = true };
            }
            catch (Exception ex)
            {
                return new Result { IsSuccess = false, ErroMessage = ex.Message, Data = null };
            }
        }

        public Result DisConnect()
        {
            try
            {
                if (!Clien.IsOpen) return new Result { IsSuccess = true };
                Clien.Close();
                IsOpen = Clien.IsOpen;
                return new Result { IsSuccess = true };
            }
            catch (Exception ex)
            {
                return new Result { IsSuccess = false, ErroMessage = ex.Message };
            }
        }

        /// <summary>
        /// 查询判定数据和结果
        /// </summary>
        /// <param name="localID"></param>
        /// <returns></returns>
        public Result<RJ6902R0X59> GetTestDataAndResult(byte localID)
        {
            try
            {
                Result result = ShortCircuitCommand(CommandEnum.查询测试判定数据和结果RJ6902R, localID);
                if (result.IsSuccess)
                {
                    byte[] data = result.Data.Skip(6).ToArray();
                    byte[] v1 = new byte[] { data[10], data[11], data[12], data[13] };
                    var v2 = v1.Select(x => x.ToString("X2"));
                    var v3 = string.Join("", v2);
                    Result<RJ6902R0X59> RjResult = new Result<RJ6902R0X59>
                    {
                        Data = result.Data,
                        Content = new RJ6902R0X59
                        {
                            Drop1 = Convert.ToInt32(data[0].ToString("X2") + data[1].ToString("X2"), 16),
                            Drop2 = Convert.ToInt32(data[2].ToString("X2") + data[3].ToString("X2"), 16),
                            Drop3 = Convert.ToInt32(data[4].ToString("X2") + data[5].ToString("X2"), 16),
                            Voltage = Convert.ToInt32(data[6].ToString("X2") + data[7].ToString("X2"), 16),
                            UpperTime = Convert.ToInt32(data[8].ToString("X2") + data[9].ToString("X2"), 16),
                            Resistance = (float)UInt32.Parse(v3, System.Globalization.NumberStyles.HexNumber) / 10,
                            ResidueVoltage = Convert.ToInt32(data[14].ToString("X2") + data[15].ToString("X2"), 16),
                            OpenResult = GetResult(data[16]),
                            VoltageResult1 = GetResult(data[17]),
                            VoltageResult2 = GetResult(data[18]),
                            VPResult = GetResult(data[19]),
                            Drop1Result = GetResult(data[20]),
                            Drop2Result = GetResult(data[21]),
                            Drop3Result = GetResult(data[22]),
                            TLResult = GetResult(data[23]),
                            THResult = GetResult(data[24]),
                            ResistanceResult = GetResult(data[25]),
                            ResidueVoltageResult = GetResult(data[26]),
                            Result = GetResult(data[27])
                        },
                        ErroMessage = "",
                        IsSuccess = true,
                    };
                    return RjResult;
                }
                else
                {
                    return new Result<RJ6902R0X59> { Content = null, Data = result.Data, ErroMessage = result.ErroMessage, IsSuccess = false };
                }
            }
            catch (Exception ex)
            {
                Logger.Info($" 获取短路测试结果异常:{ex}");
                return new Result<RJ6902R0X59> { Content = null, Data = null, ErroMessage = ex.Message, IsSuccess = false };
            }
        }

        /// <summary>
        /// 获取波形信息 设定值
        /// </summary>
        /// <param name="localID"></param>
        /// <returns></returns>
        public Result<RJ6902R0X6B> GetWaveInfo(byte localID)
        {
            try
            {
                Result result = ShortCircuitCommand(CommandEnum.查询标准波形信息RJ6902R, localID);
                if (result.IsSuccess)
                {
                    byte[] data = result.Data.Skip(6).ToArray();
                    Logger.Info($"查询标准波形信息RJ6902R {string.Join(",",data.Select(s=>s.ToString("X2")))}");
                    Result<RJ6902R0X6B> RjResult = new Result<RJ6902R0X6B>
                    {
                        Data = result.Data,
                        Content = new RJ6902R0X6B
                        {
                            Val1 = Convert.ToUInt64(String.Join("", data.Skip(0).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val2 = Convert.ToUInt64(String.Join("", data.Skip(2).Take(8).Select(s => s.ToString("X2"))), 16),
                            Val3 = Convert.ToUInt64(String.Join("", data.Skip(10).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val4 = Convert.ToUInt64(String.Join("", data.Skip(12).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val5 = Convert.ToUInt64(String.Join("", data.Skip(14).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val6 = Convert.ToUInt64(String.Join("", data.Skip(16).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val7 = Convert.ToUInt64(String.Join("", data.Skip(18).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val8 = Convert.ToUInt64(String.Join("", data.Skip(20).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val9 = Convert.ToUInt64(String.Join("", data.Skip(22).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val10 = Convert.ToUInt64(String.Join("", data.Skip(24).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val11 = Convert.ToUInt64(String.Join("", data.Skip(26).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val12 = Convert.ToUInt64(String.Join("", data.Skip(28).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val13 = Convert.ToUInt64(String.Join("", data.Skip(30).Take(4).Select(s => s.ToString("X2"))), 16),
                            Val14 = Convert.ToUInt64(String.Join("", data.Skip(34).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val15 = Convert.ToUInt64(String.Join("", data.Skip(36).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val16 = Convert.ToUInt64(String.Join("", data.Skip(38).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val17 = Convert.ToUInt64(String.Join("", data.Skip(40).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val18 = Convert.ToUInt64(String.Join("", data.Skip(42).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val19 = Convert.ToUInt64(String.Join("", data.Skip(44).Take(2).Select(s => s.ToString("X2"))), 16),
                            Val20 = Convert.ToUInt64(String.Join("", data.Skip(46).Take(4).Select(s => s.ToString("X2"))), 16),
                            Val21 = Convert.ToUInt64(String.Join("", data.Skip(50).Take(2).Select(s => s.ToString("X2"))), 16), 
                        },
                        ErroMessage = "",
                        IsSuccess = true,
                    };
                    return RjResult;
                }
                else
                {
                    return new Result<RJ6902R0X6B> { Content = null, Data = result.Data, ErroMessage = result.ErroMessage, IsSuccess = false };
                }
            }
            catch (Exception ex)
            {
                return new Result<RJ6902R0X6B> { Content = null, Data = null, ErroMessage = $"{ex}", IsSuccess = false };
            }
        }

        public void GetParameter()
        {

        }

        /// <summary>
        /// 启动命令
        /// </summary>
        /// <param name="command">命令</param>
        /// <param name="localID">从机地址</param>
        /// <returns></returns>
        private Result ShortCircuitCommand(CommandEnum command, byte localID)
        {
            try
            {
                List<byte> cmd = new byte[] { 0x7B, 0x00, 0x08, localID, CommandByte(command), (byte)command, 0x7D }.ToList();
                GetCheckNumber(ref cmd);
                Logger.Info($"发送字节:{string.Join(",", cmd.Select(x => x.ToString("X2")))} 长度:{cmd.Count}");
                Clien.Write(cmd.ToArray(), 0, cmd.Count);
                var bytes = new List<byte>();
                while (true)
                {
                    var b=Clien.ReadByte();
                    bytes.Add((byte)b);
                    if (b == 125) break;
                }
               // string value = Clien.ReadTo(Encoding.ASCII.GetString(new byte[] { 0x7D }));
               // byte[] data = Encoding.ASCII.GetBytes(value);
                Logger.Info($"返回字节:{string.Join(",", bytes.Select(s => s.ToString("X2")))} 长度:{bytes.Count}");
                return GetResult(bytes.ToArray());
            }
            catch (Exception ex)
            {
                return new Result { Data = null, ErroMessage = ex.Message, IsSuccess = false };
            }
        }
        public Result<bool?> GetTestResult(byte localID)
        {
            try
            {
                Result result = ShortCircuitCommand(CommandEnum.查询测试结果RJ6902R, localID);
                if (result.IsSuccess)
                {

                    byte[] data = result.Data.Skip(6).Take(1).ToArray();
                    return new Result<bool?>
                    {
                        Data = result.Data,
                        Content = GetResult(data[0]),
                        ErroMessage = "",
                        IsSuccess = true
                    };
                }
                else
                {
                    return new Result<bool?> { Content = null, Data = result.Data, ErroMessage = result.ErroMessage, IsSuccess = false };
                }
            }
            catch (Exception ex)
            {
                return new Result<bool?> { Content = null, Data = null, ErroMessage = ex.Message, IsSuccess = false };
            }
        }

        public Result StartTest(byte localID)
        {
            return ShortCircuitCommand(CommandEnum.启动测试, localID);
        }

        /// <summary>
        /// 获取命令字节
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        private byte CommandByte(CommandEnum command)
        {
            switch (command)
            {
                case CommandEnum.启动测试:
                case CommandEnum.启动采集:
                case CommandEnum.保存采集波形:
                    return 0x0F;
                case CommandEnum.查询当前标准波形数据RJ6902B:
                case CommandEnum.查询测试波形数据RJ6902B:
                case CommandEnum.查询测试判定数据和结果RJ6902B:
                case CommandEnum.查询测试结果RJ6902B:
                case CommandEnum.查询标准波形信息RJ6902B:
                case CommandEnum.查询当前标准波形数据及参数RJ6902B:
                case CommandEnum.查询标准波形信息RJ6902R:
                default:
                    return 0xF0;
            }
        }


        /// <summary>
        /// 返回结果
        /// </summary>
        /// <param name="b">结果字节</param>
        /// <returns>对单一字节进行分析并返回的结果，返回null标识无测试结果,true表示OK,false表示NG</returns>
        protected virtual bool? GetResult(byte b)
        {
            switch (b)
            {
                case 0:
                    return null;
                case 1:
                    return true;
                case 0xFF:
                default:
                    return false;
            }
        }

        public Result GetResult(byte[] data)
        {
            try
            {
                byte val = data[data.Length - 1];
                Result result = new Result();
                switch (val)
                {
                    case 0x01:
                        result.ErroMessage = "校验和错误";
                        break;
                    case 0x02:
                        result.ErroMessage = "命令类型错误";
                        break;
                    case 0x03:
                        result.ErroMessage = "命令字错误";
                        break;
                    case 0x04:
                        result.ErroMessage = "状态不符";
                        break;
                    case 0x05:
                        result.ErroMessage = "参数错误(参数无效或个数不符)";
                        break;
                    default:
                        result.IsSuccess = true;
                        result.ErroMessage = "";
                        break;
                }
                result.Data = data;
                return result;
            }
            catch (Exception ex)
            {
                return new Result { Data = data, ErroMessage = ex.Message, IsSuccess = false };
            }
        }

        /// <summary>
        /// 获取校验和
        /// </summary>
        /// <param name="cn">发送报文</param>
        protected void GetCheckNumber(ref List<byte> cn)
        {
            int val = 0;
            try
            {
                for (int i = 0; i < cn.Count; i++)
                {
                    if (i == 0 || i == cn.Count - 1)
                    {
                        continue;
                    }
                    val += cn[i];
                }
                cn.Insert(cn.Count - 1, byte.Parse(int.Parse(val.ToString("X").Substring(val.ToString().Length - 2), System.Globalization.NumberStyles.HexNumber).ToString()));
            }
            catch (Exception)
            {

            }
        }
    }
}
